package com.library.books.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.library.books.domain.BookShelf;
import com.library.books.domain.dto.BookShelfGenerateDto;
import com.library.books.domain.vo.BookShelfBooksCopyCount;
import com.library.books.domain.vo.BookShelfChildCount;
import com.library.books.domain.vo.BookShelfJoinBooksJoinBooksCopy;
import com.library.books.domain.vo.BookShelfUsageVo;
import com.library.books.mapper.BookShelfMapper;
import com.library.books.service.IBookShelfService;
import com.library.common.constant.HttpStatus;
import com.library.common.utils.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 书架Service业务层处理
 *
 * @author hb
 * @date 2024-10-14
 */
@Service
public class BookShelfServiceImpl extends ServiceImpl<BookShelfMapper, BookShelf> implements IBookShelfService
{

    /**
     * 查询书架列表
     *
     *
     * @param bookShelf 书架
     * @return 书架
     */
    @Override
    public List<BookShelf> selectBookShelfList(BookShelf bookShelf) {
        return baseMapper.selectBookShelfList(bookShelf);
    }

    /**
     * 书架树形结构查询列表
     *
     * @return 书架树形集合
     */
    @Override
    public List<BookShelf> findByParentId() {
        return baseMapper.findByParentId();
    }

    /**
     * 新增多个书架
     *  - 以行列的方式快速新增书架
     * @param bookShelf 架子参数
     * @return 1
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addGrid(BookShelfGenerateDto bookShelf) {
        // 顶级架子
        int insert = this.getBaseMapper().insert(bookShelf);
        if(insert > 0) {
            // 检查架子是否有格子参数
            if(bookShelf.getBookShelfRows() > 0 && bookShelf.getBookShelfCols() > 0) {
                // 子级架子
                List<BookShelf> shelfList = new ArrayList<>();
                for (int i = 1 ; i <= bookShelf.getBookShelfRows() * bookShelf.getBookShelfCols() ; i++) {

                    BookShelf childBookShelf = new BookShelf();
                    childBookShelf.setParentId(bookShelf.getBookShelfId());
                    childBookShelf.setBookShelfName(String.format("%s-%02d", bookShelf.getBookShelfName(), i));
                    childBookShelf.setBookShelfStatus(bookShelf.getBookShelfStatus());
                    shelfList.add(childBookShelf);
                }
                saveBatch(shelfList);
            }
            // 小格子也是格子
            return HttpStatus.SUCCESS;
        }
        throw new RuntimeException("添加失败");
    }


    /**
     * 删除架子数据
     * @param asList 删除的架子列表
     * @return 删除
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeByShelfIds(List<Long> asList) {
        String notice = "";

        List<BookShelf> list = list(Wrappers.lambdaQuery(BookShelf.class)
            .in(BookShelf::getBookShelfId, asList)
        );
        // 不同的架子数据
        List<Long> rootList = list.stream().filter(b -> 0 == b.getParentId()).map(BookShelf::getBookShelfId).collect(Collectors.toList());
        List<Long> childList = list.stream().filter(b -> 0 != b.getParentId()).map(BookShelf::getBookShelfId).collect(Collectors.toList());

        // 没有子架子的数据进行删除
        int deleteRoot = 0 ;
        if(rootList.size() > 0) {
            List<BookShelfChildCount> bookShelfChildCount = this.getBaseMapper().selectBookShelfChildCountById(rootList);
            List<Long> collect = bookShelfChildCount.stream().filter(b -> b.getBookShelfChildCount() == 0).map(BookShelfChildCount::getBookShelfId).collect(Collectors.toList());
            if(collect.size() > 0) {
                deleteRoot += this.getBaseMapper().delete(Wrappers.lambdaQuery(BookShelf.class)
                    .in(BookShelf::getBookShelfId, collect)
                );
            }
        }

        // 没有书籍的架子数据进行删除
        int deleteChild = 0 ;
        if(childList.size() > 0) {
            List<BookShelfBooksCopyCount> bookShelfBooksCopyCount = this.getBaseMapper().selectBookShelfBooksCopyCountById(childList);
            List<Long> collect = bookShelfBooksCopyCount.stream().filter(b -> b.getBooksCopyCount() == 0).map(BookShelfBooksCopyCount::getBookShelfId).collect(Collectors.toList());
            if(collect.size() > 0) {
                deleteChild += this.getBaseMapper().delete(Wrappers.lambdaQuery(BookShelf.class)
                    .in(BookShelf::getBookShelfId, collect)
                );
            }
        }
        return deleteRoot + deleteChild;
    }

    /**
     * 查询整齐的架子列表
     */
    @Override
    public List<BookShelf> selectBookShelfTidyList(BookShelf bookShelf) {
        return this.selectBookShelfList(bookShelf);
    }

    /**
     * 获取书架书籍列表详细信息
     *  - 书架的全部书籍
     */
    @Override
    public List<BookShelfJoinBooksJoinBooksCopy> selectBookShelfJoinBooksJoinBooksCopyList(BookShelf bookShelf) {
        Long parentId = bookShelf.getParentId();
        if(parentId != null && parentId == 0) {
            // 内部格子
            List<Object> innerShelf = this.listObjs(Wrappers.lambdaQuery(BookShelf.class)
                .eq(BookShelf::getParentId, bookShelf.getBookShelfId())
            );
            if(StringUtils.isNotEmpty(innerShelf)) {
                // 查询当前架子的全部书籍信息
                return this.getBaseMapper().selectBookShelfJoinBooksJoinBooksCopyList(innerShelf);
            }
        }else {
            // 查询架子单元格的全部书籍信息
            return this.getBaseMapper().selectBookShelfJoinBooksJoinBooksCopyList(List.of(bookShelf.getBookShelfId()));
        }
        return Collections.emptyList();
    }

    /**
     * 查询书架书籍使用情况列表
     * @param bookShelf 参数
     * @return 书架书籍使用情况信息列表
     */
    @Override
    public List<BookShelfUsageVo> selectBookShelfUsageInfoList(BookShelf bookShelf) {
        List<BookShelfUsageVo> bookShelfUsageVos = getBaseMapper().selectBookShelfUsageInfoList(bookShelf);
        // 处理书籍数量
        if(bookShelfUsageVos.size() > 0) {
            bookShelfUsageVos.stream()
                .filter(usage -> usage.getParentId() == 0)
                .forEach(parent -> {
                    List<BookShelfUsageVo> childStream = bookShelfUsageVos.stream().filter(child -> child.getParentId().equals(parent.getBookShelfId())).collect(Collectors.toList());
                    parent.setBooksCount(childStream.stream().map(BookShelfUsageVo::getBooksCount).reduce(0L,Long::sum));
                    parent.setBooksLend(childStream.stream().map(BookShelfUsageVo::getBooksLend).reduce(0L,Long::sum));
                });
        }
        return bookShelfUsageVos;
    }

}
